package com.qd.panda.service.info;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cdqidi.constant.ConstantDto;
import com.cdqidi.db.BaseService;
import com.cdqidi.dto.CacheKey;
import com.cdqidi.exception.ApiException;
import com.cdqidi.util.DateUtil;
import com.cdqidi.util.JacksonUtil;
import com.cdqidi.util.RedisTemplateUtil;
import com.cdqidi.util.SpringContextHolder;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.qd.common.panda.constant.PandaConstant;
import com.qd.common.panda.domain.entity.carpark.CarParkRevenueDTO;
import com.qd.common.panda.domain.entity.info.ParkInfoDTO;
import com.qd.common.panda.domain.entity.info.ParkInfoPropertyRightDTO;
import com.qd.common.panda.domain.entity.space.ParkSpaceDateDTO;
import com.qd.common.panda.domain.entity.space.ParkSpaceTenantDTO;
import com.qd.common.sys.domain.entity.upload.FileUploadDTO;
import com.qd.common.sys.enums.BaseTableEnum;
import com.qd.panda.mapper.info.ParkInfoMapper;
import com.qd.panda.mapper.space.ParkSpaceMapper;
import com.qd.panda.model.CarPark;
import com.qd.panda.model.CarParkLocation;
import com.qd.panda.model.ParkInfo;
import com.qd.panda.service.park.CarParkLocationService;
import com.qd.panda.service.park.CarParkRevenueService;
import com.qd.panda.service.park.CarParkService;
import com.qd.panda.service.space.ParkSpaceDateService;
import com.qd.panda.service.space.ParkSpaceTenantService;
import com.qd.system.service.dict.MbUtil;
import com.qd.system.service.login.LoginUserService;
import com.qd.system.service.org.OrgService;
import com.qd.system.service.user.BaseUserInfoService;
import com.qd.system.service.user.UserOperatorService;
import com.qd.system.util.FileConfirmUtil;
import com.qd.upload.constant.FileConfirmDTO;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.*;

import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;

/**
 * 车位信息
 *
 * @author sjk
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class ParkInfoService extends BaseService<ParkInfoMapper, ParkInfo> {

    private static final String PREFIX_ID = "panda_park_info_aid_{0}";

    private final RedisTemplateUtil<ParkInfo> redisTemplateUtil;
    private final ParkInfoPicService parkInfoPicService;
    private final ParkInfoPropertyRightService parkInfoPropertyRightService;
    private final CarParkService carParkService;
    private final CarParkLocationService carParkLocationService;
    private final CarParkRevenueService carParkRevenueService;
    private final ParkSpaceNumberService parkSpaceNumberService;
    private final ParkSpaceTenantService parkSpaceTenantService;
    private final BaseUserInfoService baseUserInfoService;
    private final ParkSpaceMapper parkSpaceMapper;
    private final ParkSpaceDateService parkSpaceDateService;

    /**
     * 保存
     *
     * @param dto 页面对象
     * @return 页面对象
     */
    @Transactional(rollbackFor = Exception.class)
    public ParkInfoDTO save(ParkInfoDTO dto) {
        validator(dto);
        saveChild(dto);
        final ParkInfo model = dtoToModel(dto);
        try {
            if (super.save(model)) {
                return modelToDto(model);
            }
            throw new ApiException("添加失败");
        } finally {
            clearCache(model);
            model.freeData();
        }
    }

    /**
     * 修改
     *
     * @param dto 页面对象
     * @return 页面对象
     */
    @Transactional(rollbackFor = Exception.class)
    public ParkInfoDTO update(ParkInfoDTO dto) {
        validator(dto);
        saveChild(dto);
        final ParkInfo historyModel = Optional.ofNullable(getById(dto.getAid())).orElseThrow(() -> new ApiException("ID不存在,不能更新"));
        final ParkInfo model = dtoToModel(dto);
        try {
            if (super.updateById(model)) {
                return modelToDto(model);
            }
            throw new ApiException("更新失败");
        } finally {
            clearCache(historyModel);
            historyModel.freeData();
            model.freeData();
        }
    }

    /**
     * 批量添加
     *
     * @param mList 数据库对象
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveBatch(List<ParkInfo> mList) {
        try {
            if (!super.saveBatch(mList)) {
                throw new ApiException("批量添加失败");
            }
        } finally {
            clearCaches(mList);
        }
    }

    /**
     * 删除，单个
     *
     * @param aid 主键
     */
    @Transactional(rollbackFor = Exception.class)
    public void removeById(String aid) {
        final ParkInfo historyModel = Optional.ofNullable(getById(aid)).orElseThrow(() -> new ApiException("数据不存在,不能删除"));
        try {
            parkInfoPicService.deleteByAid(aid);
            parkInfoPropertyRightService.deleteByAid(aid);
            if (!super.removeById(aid)) {
                throw new ApiException("删除失败");
            }
        } finally {
            clearCache(historyModel);
            historyModel.freeData();
        }
    }

    /**
     * 批量删除
     *
     * @param ids 主键集合
     */
    @Transactional(rollbackFor = Exception.class)
    public void removeBatchIds(List<String> ids) {
        final List<ParkInfo> historyModelList = checkIds(ids);
        try {
            Set<String> aidList = historyModelList.stream().map(ParkInfo::getAid).collect(toSet());
            for (String aid : aidList) {
                parkInfoPicService.deleteByAid(aid);
                parkInfoPropertyRightService.deleteByAid(aid);
            }
            aidList.clear();
            if (!super.removeByIds(ids)) {
                throw new ApiException("批量删除失败");
            }
        } finally {
            clearCaches(historyModelList);
            historyModelList.clear();
        }
    }

    /**
     * 根据传入对象构建查询参数，判断是否存在
     *
     * @param dto 参数
     * @return 存在为true
     */
    @Transactional(readOnly = true)
    public Boolean isExists(ParkInfoDTO dto) {
        final QueryWrapper<ParkInfo> queryWrapper = createQueryWrapper(dto);
        final boolean exists = super.count(queryWrapper) > 0;
        queryWrapper.clear();
        return exists;
    }

    /**
     * 根据主键判断数据是否存在
     *
     * @param aid 主键
     * @return 存在为true
     */
    @Transactional(readOnly = true)
    public Boolean isExistsById(String aid) {
        boolean exists = false;
        if (StringUtils.hasLength(aid)) {
            final ParkInfo model = getById(aid);
            exists = (null != model);
            if (exists) {
                model.freeData();
            }
        }
        return exists;
    }

    /**
     * 根据主键获取数据
     *
     * @param aid 主键
     * @return 单条记录
     */
    @Transactional(readOnly = true)
    public ParkInfo getById(String aid) {
        final String key = RedisTemplateUtil.getRedisCacheKey(PREFIX_ID, aid);
        return redisTemplateUtil.get(new CacheKey().setKey(key).setTimeout(ConstantDto.REDIS_TIME_OUT_DAY), () -> super.getById(aid), ParkInfo.class);
    }

    /**
     * 根据主键获取数据
     *
     * @param aid 主键
     * @return 单条记录，转换成页面对象
     */
    @Transactional(readOnly = true)
    public ParkInfoDTO getByIdDto(String aid) {
        ParkInfoDTO parkInfoDTO = Optional.ofNullable(getById(aid)).map(this::modelToDto).orElse(null);
        Optional.ofNullable(parkInfoDTO).ifPresent(d ->{
            buildDisplay(d);
            buildChild(d);
        });
        return parkInfoDTO;
    }

    /**
     * 根据条件查询单条数据
     *
     * @param dto 查询参数
     * @return 单条记录
     */
    @Transactional(readOnly = true)
    public ParkInfo getOne(ParkInfoDTO dto) {
        final QueryWrapper<ParkInfo> queryWrapper = createQueryWrapper(dto);
        ParkInfo model = super.getOne(queryWrapper);
        queryWrapper.clear();
        return model;
    }

    /**
     * 根据条件查询单条数据
     *
     * @param dto 查询参数
     * @return 单条记录，转换成页面对象
     */
    @Transactional(readOnly = true)
    public ParkInfoDTO getOneDto(ParkInfoDTO dto) {
        return Optional.ofNullable(getOne(dto)).map(this::modelToDto).orElse(null);
    }

    /**
     * 根据条件查询列表数据
     *
     * @param dto 查询参数
     * @return 列表数据
     */
    @Transactional(readOnly = true)
    public List<ParkInfo> getList(ParkInfoDTO dto) {
        final QueryWrapper<ParkInfo> queryWrapper = createQueryWrapper(dto);
        final List<ParkInfo> list = super.list(queryWrapper);
        queryWrapper.clear();
        return list;
    }

    /**
     * 根据条件查询列表数据
     *
     * @param dto 查询参数
     * @return 列表数据，转换成页面对象
     */
    @Transactional(readOnly = true)
    public List<ParkInfoDTO> getListDto(ParkInfoDTO dto) {
        return modelToDtoList(getList(dto));
    }

    /**
     * 分页数据
     *
     * @param page 分页对象
     * @param dto  查询参数
     * @return 分页信息
     */
    @Transactional(readOnly = true)
    public IPage<ParkInfoDTO> page(Page<ParkInfo> page, ParkInfoDTO dto) {
        final QueryWrapper<ParkInfo> queryWrapper = createQueryWrapper(dto);
        UserOperatorService.buildInSql(dto, queryWrapper);
        queryWrapper.orderByDesc("add_time,park_id");
        Page<ParkInfo> iPage = baseMapper.selectPage(page, queryWrapper);
        queryWrapper.clear();
        return iPage.convert(this::modelToDto);
    }

    /**
     * 分页数据
     *
     * @param page 分页对象
     * @param dto  查询参数
     * @return 分页信息
     */
    @Transactional(readOnly = true)
    public IPage<ParkInfoDTO> myPage(Page<ParkInfo> page, ParkInfoDTO dto) {
        final QueryWrapper<ParkInfo> queryWrapper = createQueryWrapper(dto);
        UserOperatorService.buildInSql(dto, queryWrapper);
        queryWrapper.orderByDesc("add_time");
        Page<ParkInfo> iPage = baseMapper.selectPage(page, queryWrapper);
        queryWrapper.clear();
        return iPage.convert(this::modelToDto);
    }

    /**
     * 分页数据
     *
     * @param page 分页对象
     * @param dto  查询参数
     * @return 分页信息
     */
    @Transactional(readOnly = true)
    public IPage<ParkInfoDTO> appPage(Page<ParkInfo> page, ParkInfoDTO dto) {
        final QueryWrapper<ParkInfo> queryWrapper = createQueryWrapper(dto);
        queryWrapper.orderByDesc("add_time");
        Page<ParkInfo> iPage = baseMapper.selectPage(page, queryWrapper);
        queryWrapper.clear();
        return iPage.convert(this::modelToDto);
    }

    /**
     * 清空缓存
     *
     * @param model 数据库对象
     */
    public void clearCache(ParkInfo model) {
        if (null == model) {
            return;
        }
        redisTemplateUtil.deleteByKey(RedisTemplateUtil.getRedisCacheKey(PREFIX_ID, model.getAid()));
    }

    /**
     * 批量清空缓存
     *
     * @param list 数据库对象
     */
    public void clearCaches(List<ParkInfo> list) {
        if (null == list || list.isEmpty()) {
            return;
        }
        List<String> ids = list.stream().map(model -> RedisTemplateUtil.getRedisCacheKey(PREFIX_ID, model.getAid())).collect(toList());
        if (!ids.isEmpty()) {
            redisTemplateUtil.deleteByKey(ids);
            ids.clear();
        }
    }

    /**
     * 数据库对象转页面对象
     *
     * @param model 数据库对象
     * @return 页面对象
     */
    public ParkInfoDTO modelToDto(ParkInfo model) {
        if (null == model) {
            return null;
        }
        final ParkInfoDTO dto = new ParkInfoDTO();
        dto.setAid(model.getAid());
        dto.setRegion(model.getRegion());
        dto.setRegionName(model.getRegionName());
        dto.setAddress(model.getAddress());
        dto.setSpaceNumber(model.getSpaceNumber());
        dto.setSysSpaceNumber(model.getSysSpaceNumber());
        dto.setNote(model.getNote());
        dto.setAddTime(model.getAddTime());
        dto.setUpdateTime(model.getUpdateTime());
        dto.setApprovalStatus(model.getApprovalStatus());
        dto.setApprovalResult(model.getApprovalResult());
        dto.setApprovalTime(model.getApprovalTime());
        dto.setApprovalUnit(model.getApprovalUnit());
        dto.setApplicant(model.getApplicant());
        dto.setParkId(model.getParkId());
        dto.setParkSpaceSize(model.getParkSpaceSize());
        dto.setParkSpaceType(model.getParkSpaceType());
        dto.setApprovalUser(model.getApprovalUser());
        dto.setPlanPic(model.getPlanPic());
        buildDisplay(dto);
        return dto;
    }

    /**
     * 页面对象转数据库对象
     *
     * @param dto 页面对象
     * @return 数据库对象
     */
    public ParkInfo dtoToModel(ParkInfoDTO dto) {
        if (null == dto) {
            return null;
        }
        final ParkInfo model = new ParkInfo();
        model.setAid(dto.getAid());
        model.setRegion(dto.getRegion());
        model.setRegionName(dto.getRegionName());
        model.setAddress(dto.getAddress());
        model.setSpaceNumber(dto.getSpaceNumber());
        model.setSysSpaceNumber(dto.getSysSpaceNumber());
        model.setNote(dto.getNote());
        model.setAddTime(dto.getAddTime());
        model.setUpdateTime(dto.getUpdateTime());
        model.setApprovalStatus(dto.getApprovalStatus());
        model.setApprovalResult(dto.getApprovalResult());
        model.setApprovalTime(dto.getApprovalTime());
        model.setApprovalUnit(dto.getApprovalUnit());
        model.setApplicant(dto.getApplicant());
        model.setParkId(dto.getParkId());
        model.setParkSpaceSize(dto.getParkSpaceSize());
        model.setParkSpaceType(dto.getParkSpaceType());
        model.setApprovalUser(dto.getApprovalUser());
        model.setPlanPic(dto.getPlanPic());
        return model;
    }

    /**
     * 码表转换
     *
     * @param dto 页面对象
     */
    public void buildDisplay(ParkInfoDTO dto) {
        if (!StringUtils.hasLength(dto.getParkIdDisplay())) {
            dto.setParkIdDisplay(carParkService.idToDisplay(dto.getParkId()));
        }
        if (!StringUtils.hasLength(dto.getApprovalUnitDisplay())) {
            dto.setApprovalUnitDisplay(SpringContextHolder.getBean(OrgService.class).idToDisplay(dto.getApprovalUnit()));
        }
        if (!StringUtils.hasLength(dto.getApprovalUserDisplay())) {
            dto.setApprovalUserDisplay(SpringContextHolder.getBean(LoginUserService.class).idToDisplay(dto.getApprovalUser()));
        }
        if (!StringUtils.hasLength(dto.getParkSpaceTypeDisplay())) {
            dto.setParkSpaceTypeDisplay(MbUtil.idToDisplay(dto.getParkSpaceType()));
        }
        if (!StringUtils.hasLength(dto.getParkSpaceSizeDisplay())) {
            dto.setParkSpaceSizeDisplay(MbUtil.idToDisplay(dto.getParkSpaceSize()));
        }
        if (StringUtils.hasLength(dto.getPlanPic())) {
            if (!dto.getPlanPic().startsWith(ConstantDto.HTTP) && !dto.getPlanPic().startsWith(ConstantDto.HTTPS)) {
                dto.setPlanPic(FileConfirmUtil.getImageFile(dto.getPlanPic()));
            }
        }
        Optional.ofNullable(baseUserInfoService.getById(dto.getApplicant())).ifPresent(b-> dto.setMobile(b.getMobile()));
    }

    public void buildChild(ParkInfoDTO dto) {
        if (null == dto.getPicList()) {
            dto.setPicList(parkInfoPicService.getListByAidDTO(dto.getAid()));
        }
        if (null == dto.getPropertyRightList()) {
            dto.setPropertyRightList(parkInfoPropertyRightService.getListByAidDTO(dto.getAid()));
        }
    }

    /**
     * 数据库对象转页面对象
     *
     * @param list 数据库对象
     * @return 页面对象
     */
    public List<ParkInfoDTO> modelToDtoList(List<ParkInfo> list) {
        return Optional.ofNullable(list).orElse(Collections.emptyList()).stream().map(this::modelToDto).collect(toList());
    }

    /**
     * 页面对象转数据库对象
     *
     * @param list 页面对象
     * @return 数据库对象
     */
    public List<ParkInfo> dtoToModelList(List<ParkInfoDTO> list) {
        return Optional.ofNullable(list).orElse(Collections.emptyList()).stream().map(this::dtoToModel).collect(toList());
    }

    /**
     * 拼装查询参数，除了主键的其他字段会自动加入进来
     *
     * @param dto 查询参数，不为空的属性会被自动加入
     */
    public QueryWrapper<ParkInfo> createQueryWrapper(ParkInfoDTO dto) {
        final QueryWrapper<ParkInfo> queryWrapper = new QueryWrapper<>();
        if (null != dto) {
            if (StringUtils.hasLength(dto.getSpaceNumber())) {
                queryWrapper.eq("space_number", dto.getSpaceNumber());
            }
            if (StringUtils.hasLength(dto.getSysSpaceNumber())) {
                queryWrapper.eq("sys_space_number", dto.getSpaceNumber());
            }
            if (StringUtils.hasLength(dto.getApprovalResult())) {
                queryWrapper.eq("approval_result", dto.getApprovalResult());
            }
            if (StringUtils.hasLength(dto.getApprovalUnit())) {
                queryWrapper.eq("approval_unit", dto.getApprovalUnit());
            }
            if (StringUtils.hasLength(dto.getApplicant())) {
                queryWrapper.eq("applicant", dto.getApplicant());
            }
            if (StringUtils.hasLength(dto.getParkId())) {
                queryWrapper.eq("park_id", dto.getParkId());
            }
            if (StringUtils.hasLength(dto.getParkSpaceSize())) {
                queryWrapper.eq("park_space_size", dto.getParkSpaceSize());
            }
            if (StringUtils.hasLength(dto.getParkSpaceType())) {
                queryWrapper.eq("park_space_type", dto.getParkSpaceType());
            }
            if(null != dto.getApprovalStatus()){
                queryWrapper.eq("approval_status", dto.getApprovalStatus());
            }
        }
        return queryWrapper;
    }

    /**
     * 批量检查主键在数据库中是否存在
     *
     * @param ids 主键集合
     * @return 主键查询出来的集合
     */
    public List<ParkInfo> checkIds(List<String> ids) {
        if (null == ids || ids.isEmpty()) {
            throw new ApiException("ids不能为空");
        }
        final List<ParkInfo> list = super.listByIds(ids);
        if (list.isEmpty()) {
            throw new ApiException("ids不存在" + Arrays.toString(ids.toArray()));
        }
        if (ids.size() == list.size()) {
            return list;
        }
        List<String> dbIds = list.stream().map(ParkInfo::getAid).collect(toList());
        final List<String> notExistsList = ids.stream().filter(id -> !dbIds.contains(id)).collect(toList());
        dbIds.clear();
        if (!notExistsList.isEmpty()) {
            throw new ApiException("ids不存在" + Arrays.toString(notExistsList.toArray()));
        }
        return list;
    }

    private void validator(ParkInfoDTO parkInfo) {
        if (MbUtil.isNotExists(parkInfo.getParkSpaceSize(), BaseTableEnum.PARK_SPACE_SIZE)) {
            throw new ApiException("车位大小值错误");
        }
        if (MbUtil.isNotExists(parkInfo.getParkSpaceType(), BaseTableEnum.LEASE_PARK_SPACE_TYPE)) {
            throw new ApiException("车位类型值错误");
        }
        if (null == parkInfo.getApprovalStatus()) {
            parkInfo.setApprovalStatus(PandaConstant.APPROVAL_STATUS_0);
        }
        CarPark carPark = Optional.ofNullable(carParkService.getById(parkInfo.getParkId())).orElseThrow(() -> new ApiException("停车场ID值错误"));
        if (!carPark.getParkSpaceType().equals(PandaConstant.PARK_SPACE_TYPE3)) {
            throw new ApiException("停车场类型错误");
        }
        CarParkLocation carParkLocation = Optional.ofNullable(carParkLocationService.getById(parkInfo.getParkId())).orElseThrow(() -> new ApiException("停车产位置信息错误"));
        parkInfo.setAddress(carParkLocation.getAddress());
        parkInfo.setRegion(carParkLocation.getRegion());
        parkInfo.setRegionName(carParkLocation.getRegionName());
    }

    @Transactional(rollbackFor = Exception.class)
    public ParkInfoDTO audit(ParkInfoDTO dto) {
        ParkInfo parkInfo = Optional.of(getById(dto.getAid())).orElseThrow(() -> new ApiException("车位ID值错误"));
        if (parkInfo.getApprovalStatus().equals(PandaConstant.APPROVAL_STATUS_1)) {
            throw new ApiException("已经审核通过,请勿重复操作");
        }
        if (Boolean.FALSE.equals(carParkService.isExistsById(parkInfo.getParkId()))) {
            throw new ApiException("停车场ID值错误");
        }
        clearCache(parkInfo);
        parkInfo.setParkId(parkInfo.getParkId());
        parkInfo.setApprovalTime(dto.getApprovalTime());
        parkInfo.setApprovalResult(dto.getApprovalResult());
        parkInfo.setApprovalStatus(dto.getApprovalStatus());
        parkInfo.setApprovalUnit(dto.getApprovalUnit());
        parkInfo.setApprovalUser(dto.getApprovalUser());
        if (parkInfo.getApprovalStatus().equals(PandaConstant.APPROVAL_STATUS_1) && !StringUtils.hasLength(parkInfo.getSysSpaceNumber())) {
            String sysSpaceNumber = parkSpaceNumberService.getSysSpaceNumber(parkInfo.getParkId());
            parkInfo.setSysSpaceNumber(sysSpaceNumber);
        }
        if (StringUtils.hasLength(dto.getPlanPic())) {
            if (!dto.getPlanPic().startsWith(ConstantDto.HTTP) && !dto.getPlanPic().startsWith(ConstantDto.HTTPS)) {
                parkInfo.setPlanPic(getPicPath(dto.getPlanPic()));
            }
        }
        updateById(parkInfo);
        return modelToDto(parkInfo);
    }


    public String getPicPath(String planPic) {
        FileUploadDTO fileUploadDto = new FileUploadDTO();
        fileUploadDto.setId(planPic);
        fileUploadDto.setAttachmentType(ConstantDto.ATTACHMENTTYPE_2);
        FileConfirmDTO fileConfirmDto = FileConfirmUtil.singleFileConfirm(fileUploadDto.getId(), fileUploadDto.getAttachmentType());
        if (null == fileConfirmDto) {
            throw new ApiException("文件ID不存在[" + fileUploadDto.getId() + "]");
        }
        return fileConfirmDto.getOfficialFile();
    }

    public void saveChild(ParkInfoDTO dto) {
        if (null != dto.getPicList()) {
            parkInfoPicService.saveList(dto.getAid(),dto.getPicList());
        }
        if (null != dto.getPropertyRightList()) {
            parkInfoPropertyRightService.saveList(dto.getAid(),dto.getPropertyRightList());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void removePicById(String id) {
        parkInfoPicService.removeById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    public void removePicBatchIds(List<String> ids) {
        parkInfoPicService.removeBatchIds(ids);
    }

    @Transactional(rollbackFor = Exception.class)
    public void removePropertyRightById(String id) {
        parkInfoPropertyRightService.removeById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    public void removePropertyRightBatchIds(List<String> ids) {
        parkInfoPropertyRightService.removeBatchIds(ids);
    }

    @SneakyThrows
    @Transactional(readOnly = true)
    public ArrayNode getListByApplicant(String userId) {
        QueryWrapper<ParkInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("applicant",userId);
//        queryWrapper.eq("approval_status",PandaConstant.APPROVAL_STATUS_1);
        queryWrapper.select("aid", "region", "region_name", "address", "space_number", "sys_space_number", "park_id", "approval_status","approval_result","add_time");
        queryWrapper.orderByDesc("add_time");
        queryWrapper.orderByAsc("approval_status");
        List<ParkInfo> list = super.list(queryWrapper);
        queryWrapper.clear();
        ArrayNode nodes = JacksonUtil.getObjectMapper().createArrayNode();
        if(!list.isEmpty()){
            LocalDate now = LocalDate.now();
            for (ParkInfo parkInfo : list) {
                ObjectNode objectNode = JacksonUtil.getObjectMapper().createObjectNode();
                objectNode.put("aid",parkInfo.getAid());
                objectNode.put("region",parkInfo.getRegion());
                objectNode.put("regionName",parkInfo.getRegionName());
                objectNode.put("address",parkInfo.getAddress());
                objectNode.put("approvalStatus", parkInfo.getApprovalStatus());
                objectNode.put("approvalResult", parkInfo.getApprovalResult());
                objectNode.put("spaceNumber",parkInfo.getSpaceNumber());
                objectNode.put("sysSpaceNumber",parkInfo.getSysSpaceNumber());
                objectNode.put("parkId",parkInfo.getParkId());
                objectNode.put("parkIdDisplay",carParkService.idToDisplay(parkInfo.getParkId()));
                objectNode.put("addTime",parkInfo.getAddTime().toString());
                CarParkRevenueDTO carParkRevenueDTO = Optional.ofNullable(carParkRevenueService.getMaxByPid(parkInfo.getParkId())).orElse(new CarParkRevenueDTO());
//                log.info("carParkRevenueDTO: {}",JacksonUtil.getObjectMapper().writeValueAsString(carParkRevenueDTO));
                if(!StringUtils.hasLength(carParkRevenueDTO.getDayRevenueDisplay())){
                    carParkRevenueDTO.setDayRevenueDisplay("0");
                }
                if(!StringUtils.hasLength(carParkRevenueDTO.getTotalRevenueDisplay())){
                    carParkRevenueDTO.setTotalRevenueDisplay("0");
                }
                objectNode.put("expectedDayRevenueDisplay",carParkRevenueDTO.getDayRevenueDisplay());
                objectNode.put("expectedTotalRevenueDisplay",carParkRevenueDTO.getTotalRevenueDisplay());
                objectNode.put("days",carParkRevenueDTO.getDays());
                List<ParkInfoPropertyRightDTO> propertyRightList = parkInfoPropertyRightService.getListByAidDTO(parkInfo.getAid());
//                List<ParkInfoPicDTO> picList = parkInfoPicService.getListByAidDTO(parkInfo.getAid());
//                objectNode.putPOJO("picList", picList);
                objectNode.putPOJO("propertyRightList", propertyRightList);
                if (parkInfo.getApprovalStatus().equals(PandaConstant.APPROVAL_STATUS_1)) {
                    Optional.ofNullable(parkSpaceMapper.getLast(userId, parkInfo.getAid(), now, now)).ifPresent(last -> {
                        ObjectNode objectLast = JacksonUtil.getObjectMapper().createObjectNode();
                        objectLast.put("sid", last.getSid());
                        objectLast.put("state", last.getState());
                        if(last.getState().equals(1)){
                            objectLast.put("stateDisplay","运行中");
                        }else if(last.getState().equals(2)){
                            objectLast.put("stateDisplay", "停运中");
                        }else{
                            objectLast.put("stateDisplay", "已租赁");
                        }
                        objectLast.put("leasableStartDate", last.getLeasableStartDate());
                        objectLast.put("leasableEndDate", last.getLeasableEndDate());
                        objectLast.put("leasableEndDate", last.getLeasableEndDate());
                        objectLast.put("days", last.getDays());
                        objectLast.put("end", last.getEnd());
                        objectLast.put("deductionTotalRevenue", last.getDeductionTotalRevenue().stripTrailingZeros().toPlainString());
                        objectLast.put("orderNum", parkSpaceTenantService.getOrderBySid(last.getSid()));
                        List<ParkSpaceDateDTO> dateList = parkSpaceDateService.getListBySidDTO(last.getSid());
                        if(null == dateList){
                            dateList = Collections.emptyList();
                        }
                        objectLast.putPOJO("dateList", dateList);
//                        //日收益
//                        BigDecimal dayRevenue = new Money(last.getExpectedDayRevenue()).multiply(last.getShareRatio()).divide(100D).getAmount();
//                        //预期总收益
//                        BigDecimal expectedTotalRevenue = new Money(last.getExpectedTotalRevenue()).multiply(last.getShareRatio()).divide(100D).getAmount();
//                        objectLast.put("dayRevenue", dayRevenue.stripTrailingZeros().toPlainString());
//                        if (last.getEnd().equals(ConstantDto.SF1)) {
//                            //已经结束,扣费后总收益如果有值就显示，没有值就显示预期总收益
//                            BigDecimal deductionTotalRevenue = last.getDeductionTotalRevenue();
//                            if (null == deductionTotalRevenue || deductionTotalRevenue.compareTo(new BigDecimal("0")) <= BigDecimal.ZERO.intValue()) {
//                                objectLast.put("totalRevenue",expectedTotalRevenue.stripTrailingZeros().toPlainString());
//                            }else{
//                                objectLast.put("totalRevenue",deductionTotalRevenue.stripTrailingZeros().toPlainString());
//                            }
//                        }else{
//                            //还没有结束，都是显示预期总收益
//                            objectLast.put("totalRevenue",expectedTotalRevenue.stripTrailingZeros().toPlainString());
//                        }
                        String leaseType = last.getLeaseType();
                        LocalTime localTime = null;
                        if(null != leaseType && leaseType.equals(PandaConstant.LEASE_TYPE_HOUR)){
                            localTime = LocalTime.now();
                        }
                        ParkSpaceTenantDTO parkSpaceTenantDTO = parkSpaceTenantService.getLastBySid(last.getSid(),LocalDate.now(),localTime);
                        if (null == parkSpaceTenantDTO) {
                            objectNode.set("lastSpaceTenant", null);
                        } else {
                            ObjectNode lastNode = JacksonUtil.getObjectMapper().createObjectNode();
                            //0表示进行中，1表示已结束
                            int state = 0;
                            LocalDate endDate = DateUtil.strToLocalDate(parkSpaceTenantDTO.getEndDate());
                            if (now.isAfter(endDate)) {
                                state = 1;
                            }
                            LocalDate startDate = DateUtil.strToLocalDate(parkSpaceTenantDTO.getStartDate());
                            if (now.isBefore(startDate)) {
                                state = 2;
                            }
                            lastNode.put("id", parkSpaceTenantDTO.getId());
                            lastNode.put("startDate", parkSpaceTenantDTO.getStartDate());
                            lastNode.put("endDate", parkSpaceTenantDTO.getEndDate());
                            lastNode.put("deductionTotalRevenueDisplay", parkSpaceTenantDTO.getDeductionTotalRevenueDisplay());
                            lastNode.put("tenantNumber", parkSpaceTenantDTO.getTenantNumber());
                            lastNode.put("orderTime", parkSpaceTenantDTO.getOrderTime().toString());
                            lastNode.put("state", state);
                            objectNode.set("lastSpaceTenant", lastNode);
                        }
//                        List<ParkInfoSpaceTenantDTO> tList = parkSpaceMapper.getList(last.getSid());
//                        if (null != tList && !tList.isEmpty()) {
//                            for (ParkInfoSpaceTenantDTO parkInfoSpaceTenantDTO : tList) {
//                                //0表示进行中，1表示已结束
//                                int state = 0;
//                                LocalDate endDate = DateUtil.strToLocalDate(parkInfoSpaceTenantDTO.getEndDate());
//                                if (now.isAfter(endDate)) {
//                                    state = 1;
//                                }
//                                LocalDate startDate = DateUtil.strToLocalDate(parkInfoSpaceTenantDTO.getStartDate());
//                                if (now.isBefore(startDate)) {
//                                    state = 2;
//                                }
//                                parkInfoSpaceTenantDTO.setState(state);
//                            }
//                            objectLast.putPOJO("spaceTenantList", tList);
//                        }
                        objectNode.set("lease", objectLast);
                    });
                }
                nodes.add(objectNode);
            }
        }
        return nodes;
    }


    @Transactional(readOnly = true)
    public List<ParkInfo> getListByParkId(String parkId) {
        QueryWrapper<ParkInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("park_id",parkId);
        queryWrapper.eq("approval_status",PandaConstant.APPROVAL_STATUS_1);
        List<ParkInfo> parkInfoList = baseMapper.selectList(queryWrapper);
        queryWrapper.clear();
        return parkInfoList;
    }
}